/**
 * Copyright 2020. javaymw.com Studio All Right Reserved
 * <p>
 * Create on 2020-06-05 21:59
 * Created by zhaoxinguo
 * Version 2.0.0
 */
package com.micai.boss.core;

import com.micai.boss.sys.entity.User;
import com.micai.boss.sys.service.UserService;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;

/**
 * @description: 自定义认证核心类
 * @author zhaoxinguo
 * @date 2020/6/5 21:59
 */
@Component
public class LoginValidateAuthenticationProvider implements AuthenticationProvider {

    @Resource
    private UserService userService;

    /**
     * 解密用的
     */
    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 进行身份验证
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //获取输入的用户名
        String username = authentication.getName();
        //获取输入的明文
        String rawPassword = (String) authentication.getCredentials();
        //查询用户是否存在
        User user = (User) userService.loadUserByUsername(username);
        if (!user.isEnabled()) {
            throw new DisabledException("该账户已被禁用，请联系管理员");
        } else if (!user.isAccountNonLocked()) {
            throw new LockedException("该账号已被锁定");
        } else if (!user.isAccountNonExpired()) {
            throw new AccountExpiredException("该账号已过期，请联系管理员");
        } else if (!user.isCredentialsNonExpired()) {
            throw new CredentialsExpiredException("该账户的登录凭证已过期，请重新登录");
        }
        //验证密码
        if (!passwordEncoder.matches(rawPassword, user.getPassword())) {
            throw new BadCredentialsException("输入密码错误!");
        }

        // TODO Spring Boot2 + Spring Security5 动态用户角色资源的权限管理(6) 添加代码
        // 设置权限信息
        Set<GrantedAuthority> grantedAuthorities  = new HashSet<>();
        for (com.micai.boss.sys.entity.Resource resource : user.getRole().getResources()) {
            //资源key作为权限标识
            grantedAuthorities.add(new SimpleGrantedAuthority(resource.getResourceKey()));
            user.setAuthorities(grantedAuthorities);
        }

        return new UsernamePasswordAuthenticationToken(user, rawPassword, user.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        //确保authentication能转成该类
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
